using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Net;

//Java namespace
using ikvm.io;
//Pellet namespaces
using org.mindswap;
using org.mindswap.pellet;
//using org.mindswap.pellet.jena.PelletReasonerFactory;
using org.mindswap.pellet.jena;
//Jena namespaces
using com.hp.hpl.jena.ontology;
using com.hp.hpl;
using com.hp.hpl.jena.rdf.model;
using com.hp.hpl.jena.reasoner;
using com.hp.hpl.jena.util.iterator;
using com.hp.hpl.jena.query;


namespace Geoconcepts.SemanticServices
{
    /// <summary>
    /// Class to query Semantic Data via SPARQL or direct queries provided by Reasoners
    /// </summary
    public class QueryEngine
    {

        /// <summary>
        /// Executes a CONSTRUCT SPARQL query over an OWL file. 
        /// No inference extensions are provided. 
        /// </summary>
        /// <param name="strCity">City name</param>
        /// <param name="strQuery">SPARQL CONSTRUCT query</param>
        /// <param name="strWebOrFile">Origin of data, "web" or "file"</param>
        /// <returns></returns>
        public byte[] ExecuteCONSTRUCTOverInferredGraph(string strCity, string strQuery)
        {
            byte[] owlGraph = null;
            Model modelInferred = ModelFactory.createDefaultModel();
            java.io.ByteArrayOutputStream ostrSubgraph = new java.io.ByteArrayOutputStream();
            string strOwlFiles = AppDomain.CurrentDomain.BaseDirectory + @"\OwlFiles";

            try
            {
                NetworkSettings.SetProxySettings();

                /*
                if (strWebOrFile == "file")
                {
                    java.io.InputStream fileIn = com.hp.hpl.jena.util.FileManager.get().open(strFullURL);
                    modelInferred.read(fileIn,null);
                }
                else
                {
                    modelInferred.read(strFullURL);
                }
                 * */
                // We have stored the owl files in memory so far


                java.io.InputStream fileIn = com.hp.hpl.jena.util.FileManager.get().open(strOwlFiles + "\\" + strCity + ".owl");
                modelInferred.read(fileIn, null);

                // If a query is not provided a trivial one is executed, retrieving all triples from URI.
                if (strQuery == null || strQuery == "")
                {
                    strQuery = "CONSTRUCT {?s ?p ?o} WHERE {?s ?p ?o .}";
                }

                Query qSparql = QueryFactory.create(strQuery);
                QueryExecution qeSparql = QueryExecutionFactory.create(qSparql, modelInferred);

                Model modelResult = qeSparql.execConstruct();

                modelResult.write(ostrSubgraph);
                owlGraph = ostrSubgraph.toByteArray();

                return owlGraph;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Executes a CONSTRUCT SPARQL query over an RDB persistenced model. 
        /// No inference extensions are provided. 
        /// </summary>
        /// <param name="strServer">Server name or IP:Port</param>
        /// <param name="strDatabase">Database name</param>
        /// <param name="strDBUser">Database user name</param>
        /// <param name="strDBPassword">Database user password</param>
        /// <param name="strModel">Name of the model to be queried</param>
        /// <param name="strQuery">Sparql query</param>
        /// <returns></returns>
        public byte[] ExecuteCONSTRUCTOverInferredGraph(string strServer,string strDatabase,string strDBUser,string strDBPassword, string strModel,string strQuery)
        {
            byte[] owlGraph = null;
            Model modelInferred = ModelFactory.createDefaultModel();
            java.io.ByteArrayOutputStream ostrSubgraph = new java.io.ByteArrayOutputStream();

            
            try
            {
                NetworkSettings.SetProxySettings();

                DataAccess svcDataAccess = new DataAccess(strServer, strDatabase, strDBUser, strDBPassword);
                svcDataAccess.openModel(strModel);


                // If a query is not provided a trivial one is executed, retrieving all triples from URI.
                if (strQuery == null || strQuery == "")
                {
                    strQuery = "CONSTRUCT {?s ?p ?o} WHERE {?s ?p ?o .}";
                }

                Query qSparql = QueryFactory.create(strQuery);
                QueryExecution qeSparql = QueryExecutionFactory.create(qSparql, svcDataAccess.ModelNamed);

                Model modelResult = qeSparql.execConstruct();

                modelResult.write(ostrSubgraph);
                owlGraph = ostrSubgraph.toByteArray();

                return owlGraph;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Used for Test Proposes
        /// </summary>
        /// <param name="strFullURL"></param>
        /// <param name="strIndividualURI"></param>
        /// <returns></returns>
        private string GetIndividual(string strFullURL, string strIndividualURI)
        {
            OntModel modelInferred = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
            java.io.ByteArrayOutputStream ostrSubgraph = new java.io.ByteArrayOutputStream();
            try
            {
                NetworkSettings.SetProxySettings();

                modelInferred.read(strFullURL);

                com.hp.hpl.jena.ontology.Individual iSubIndividual = modelInferred.getIndividual(strIndividualURI);

                return iSubIndividual.getURI();
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }
    }
}
